/*
 *    Copyright (c) 2018-2025, boss All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the boss developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: boss
 */

package com.hopes.bizz.close.visitor.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hopes.bizz.close.common.constant.CacheConstants;
import com.hopes.bizz.close.common.constant.HazardDicConstant;
import com.hopes.bizz.close.visitor.dto.ClosedHazardCarApplyDTO;
import com.hopes.bizz.close.visitor.dto.ClosedHazardCarApplyExcelDTO;
import com.hopes.bizz.close.visitor.dto.ClosedHazardCardBindGpsDTO;
import com.hopes.bizz.close.visitor.dto.ClosedVisitorApplyAuditDTO;
import com.hopes.bizz.close.visitor.entity.ClosedHazardCarApplyEntity;
import com.hopes.bizz.close.visitor.service.ClosedHazardCarApplyService;
import com.hopes.bizz.close.visitor.vo.ClosedHazardCarApplyExcelVO;
import com.hopes.boss.common.core.util.R;
import com.hopes.boss.common.excel.annotation.RequestExcel;
import com.hopes.boss.common.excel.annotation.ResponseExcel;
import com.hopes.boss.common.log.annotation.SysLog;
import com.hopes.boss.common.security.annotation.Inner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 危险品车辆预约
 *
 * @author pig
 * @date 2024-01-26 14:34:05
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/hazardapply" )
@Tag(description = "hazardapply" , name = "危险品车辆预约管理" )
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class ClosedHazardCarApplyController {

    private final ClosedHazardCarApplyService closedHazardCarApplyService;

    /**
     * 分页查询
     * @param page 分页对象
     * @param closedHazardCarApplyDTO 危险品车辆预约
     * @return
     */
    @Operation(summary = "分页查询" , description = "分页查询" )
    @GetMapping("/page" )
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_view')" )
    public R getClosedHazardCarApplyPage(Page page, ClosedHazardCarApplyDTO closedHazardCarApplyDTO) {
        final LambdaQueryWrapper<ClosedHazardCarApplyEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ObjUtil.isNotNull(closedHazardCarApplyDTO.getOrgId()), ClosedHazardCarApplyEntity::getOrgId, closedHazardCarApplyDTO.getOrgId())
                .eq(StrUtil.isNotBlank(closedHazardCarApplyDTO.getCompanyCar()), ClosedHazardCarApplyEntity::getCompanyCar, closedHazardCarApplyDTO.getCompanyCar())
                .eq(StrUtil.isNotBlank(closedHazardCarApplyDTO.getEmptyCar()), ClosedHazardCarApplyEntity::getEmptyCar, closedHazardCarApplyDTO.getEmptyCar())
                .eq(StrUtil.isNotBlank(closedHazardCarApplyDTO.getHazardType()), ClosedHazardCarApplyEntity::getHazardType, closedHazardCarApplyDTO.getHazardType())
                .eq(ObjUtil.isNotNull(closedHazardCarApplyDTO.getAuditStatus()), ClosedHazardCarApplyEntity::getAuditStatus, closedHazardCarApplyDTO.getAuditStatus())
                .eq(StrUtil.isNotBlank(closedHazardCarApplyDTO.getStatus()), ClosedHazardCarApplyEntity::getStatus, closedHazardCarApplyDTO.getStatus())
                .eq(StrUtil.isNotBlank(closedHazardCarApplyDTO.getLicencePlateNum()), ClosedHazardCarApplyEntity::getLicencePlateNum, closedHazardCarApplyDTO.getLicencePlateNum())
                .ge(ObjUtil.isNotNull(closedHazardCarApplyDTO.getStartTime()), ClosedHazardCarApplyEntity::getPlanEnterTime, closedHazardCarApplyDTO.getStartTime())
                .le(ObjUtil.isNotNull(closedHazardCarApplyDTO.getEndTime()), ClosedHazardCarApplyEntity::getPlanLeaveTime, closedHazardCarApplyDTO.getEndTime())
                .like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getLicencePlateNum, closedHazardCarApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getBillNo, closedHazardCarApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getDriverName, closedHazardCarApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getAcceptName, closedHazardCarApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getSupercargoName, closedHazardCarApplyDTO.getKeyword());
        wrapper.orderByDesc(ClosedHazardCarApplyEntity::getApplyTime);
        return R.ok(closedHazardCarApplyService.pageVO(page, wrapper));
    }

    /**
     * 分页查询（移动端）我的危险品车辆预约
     * @param page                     分页参数
     * @param closedHazardCarApplyDTO       查询参数
     * @return
     */
    @Operation(summary = "分页查询", description = "分页查询")
    @GetMapping("/selfPage")
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_view')" )
    public R getAppHazardCarApplySelfPage(Page page, ClosedHazardCarApplyDTO closedHazardCarApplyDTO) {
        return R.ok(closedHazardCarApplyService.queryAppHazardCarApplySelfPage(page, closedHazardCarApplyDTO));
    }

    /**
     * 分页查询（移动端）企业待审批的预约申请
     * @param page                          分页参数
     * @param closedHazardCarApplyDTO       查询参数
     * @return
     */
    @Operation(summary = "分页查询", description = "分页查询")
    @GetMapping("/audit/toDoPage")
    @PreAuthorize("@pms.hasPermission('hazard_hazardcar_view')" )
    public R getAppHazardCarApplyAuditToDoPage(Page page, ClosedHazardCarApplyDTO closedHazardCarApplyDTO) {
        final List<Integer> auditStatusList = Collections.singletonList(HazardDicConstant.CLOSE_HAZARD_CAR_AUDIT_STATUS_NOT_AUDIT);
        return R.ok(closedHazardCarApplyService.queryAppHazardCarApplyAuditPage(page, auditStatusList, closedHazardCarApplyDTO));
    }

    /**
     * 分页查询（移动端）企业审批完成的预约申请
     * @param page                          分页参数
     * @param closedHazardCarApplyDTO       查询参数
     * @return
     */
    @Operation(summary = "分页查询", description = "分页查询")
    @GetMapping("/audit/donePage")
    @PreAuthorize("@pms.hasPermission('hazard_hazardcar_view')" )
    public R getAppHazardCarApplyAuditDonePage(Page page, ClosedHazardCarApplyDTO closedHazardCarApplyDTO) {
        final List<Integer> auditStatusList = Arrays.asList(
                HazardDicConstant.CLOSE_HAZARD_CAR_AUDIT_STATUS_PASS_AUDIT,
                HazardDicConstant.CLOSE_FLOW_BILL_AUDIT_STATUS_NOT_PASS_AUDIT);
        return R.ok(closedHazardCarApplyService.queryAppHazardCarApplyAuditPage(page, auditStatusList, closedHazardCarApplyDTO));
    }

    /**
     * 通过id查询危险品车辆预约
     * @param id id
     * @return R
     */
    @Operation(summary = "通过id查询" , description = "通过id查询" )
    @GetMapping("/{id}" )
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_view')" )
    public R getById(@PathVariable("id" ) Long id) {
        return R.ok(closedHazardCarApplyService.getById(id));
    }


    /**
     * 根据运单号查询预约信息
     * @param billNo billNo
     * @return R
     */
    @Inner
    @Operation(summary = "根据运单号查询预约信息" , description = "根据运单号查询预约信息" )
    @GetMapping("/query/{billNo}" )
    public R getVoByBillNo(@PathVariable("billNo" ) String billNo) {
        return R.ok(closedHazardCarApplyService.getVoByBillNo(billNo));
    }

    /**
     * 新增危险品车辆预约
     * @param closedHazardCarApply 危险品车辆预约
     * @return R
     */
    @Operation(summary = "新增危险品车辆预约" , description = "新增危险品车辆预约" )
    @SysLog("新增危险品车辆预约" )
    @PostMapping
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_add')" )
    @CacheEvict(value = CacheConstants.CLOSE_HAZARD_APPLY, allEntries = true)
    public R save(@RequestBody ClosedHazardCarApplyEntity closedHazardCarApply) {
        return R.ok(closedHazardCarApplyService.save(closedHazardCarApply));
    }

    /**
     * 新增&&提交危险品车辆预约
     *
     * @param closedHazardCarApply 危险品车辆预约
     * @return R
     */
    @Operation(summary = "新增并提交危险品运输车辆", description = "新增并提交危险品运输车辆")
    @SysLog("新增并提交危险品运输车辆")
    @PostMapping("/saveAndSubmit")
    @PreAuthorize("@pms.hasPermission('hazard_hazardcar_add')")
    @CacheEvict(value = CacheConstants.CLOSE_HAZARD_APPLY, allEntries = true)
    public R saveAndSubmit(@RequestBody ClosedHazardCarApplyEntity closedHazardCarApply) {
        return R.ok(closedHazardCarApplyService.saveAndSubmit(closedHazardCarApply));
    }

    /**
     * 修改危险品车辆预约
     * @param closedHazardCarApply 危险品车辆预约
     * @return R
     */
    @Operation(summary = "修改危险品车辆预约" , description = "修改危险品车辆预约" )
    @SysLog("修改危险品车辆预约" )
    @PutMapping
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_edit')" )
    @CacheEvict(value = CacheConstants.CLOSE_HAZARD_APPLY, allEntries = true)
    public R updateById(@RequestBody ClosedHazardCarApplyEntity closedHazardCarApply) {
        return R.ok(closedHazardCarApplyService.updateById(closedHazardCarApply));
    }

    /**
     * 提交危险品车辆预约
     *
     * @param id id
     * @return R
     */
    @Operation(summary = "提交危险品车辆预约", description = "提交危险品车辆预约")
    @SysLog("提交危险品车辆预约")
    @GetMapping("/submit/{id}")
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_edit')")
    public R submitById(@PathVariable("id") Long id) {
        return R.ok(closedHazardCarApplyService.submit(id));
    }

    /**
     * 审核危险品车辆预约
     * @param closedVisitorApplyAuditDTO 审核危险品车辆预约
     * @return R
     */
    @Operation(summary = "审核危险品车辆预约" , description = "审核危险品车辆预约" )
    @SysLog("审核危险品车辆预约" )
    @PutMapping("/audit")
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_audit')" )
    public R auditById(@RequestBody ClosedVisitorApplyAuditDTO closedVisitorApplyAuditDTO) {
        return R.ok(closedHazardCarApplyService.auditById(closedVisitorApplyAuditDTO));
    }

    /**
     * 危险化学品车辆GPS设备绑定
     * @param closedHazardCardBindGpsDTO GPS设备绑定对象
     * @return R
     */
    @Operation(summary = "危险化学品车辆GPS设备绑定" , description = "危险化学品车辆GPS设备绑定" )
    @SysLog("危险化学品车辆GPS设备绑定" )
    @PutMapping("/gps/operate")
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_edit')" )
    @CacheEvict(value = CacheConstants.CLOSE_HAZARD_APPLY, allEntries = true)
    public R bindGpsById(@RequestBody ClosedHazardCardBindGpsDTO closedHazardCardBindGpsDTO) {
        return R.ok(closedHazardCarApplyService.operateGpsDevice(closedHazardCardBindGpsDTO));
    }


    /**
     * 通过id删除危险品车辆预约
     * @param ids id列表
     * @return R
     */
    @Operation(summary = "通过id删除危险品车辆预约" , description = "通过id删除危险品车辆预约" )
    @SysLog("通过id删除危险品车辆预约" )
    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_del')" )
    @CacheEvict(value = CacheConstants.CLOSE_HAZARD_APPLY, allEntries = true)
    public R removeById(@RequestBody Long[] ids) {
        return R.ok(closedHazardCarApplyService.removeBatchByIds(CollUtil.toList(ids)));
    }

    /**
     * excel模板
     *
     * @return excel 文件流
     */
    @ResponseExcel
    @GetMapping("/template")
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_export')")
    public List<ClosedHazardCarApplyExcelVO> template() {
        return closedHazardCarApplyService.exportExcel(Collections.singletonList(new ClosedHazardCarApplyEntity()));
    }

    /**
     * 导出excel 表格
     * @param closedHazardCarApplyDTO 查询条件
     * @return excel 文件流
     */
    @ResponseExcel
    @GetMapping("/export")
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_export')")
    public List<ClosedHazardCarApplyExcelVO> export(ClosedHazardCarApplyDTO closedHazardCarApplyDTO) {
        final LambdaQueryWrapper<ClosedHazardCarApplyEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ObjUtil.isNotNull(closedHazardCarApplyDTO.getOrgId()), ClosedHazardCarApplyEntity::getOrgId, closedHazardCarApplyDTO.getOrgId())
                .eq(StrUtil.isNotBlank(closedHazardCarApplyDTO.getCompanyCar()), ClosedHazardCarApplyEntity::getCompanyCar, closedHazardCarApplyDTO.getCompanyCar())
                .eq(StrUtil.isNotBlank(closedHazardCarApplyDTO.getEmptyCar()), ClosedHazardCarApplyEntity::getEmptyCar, closedHazardCarApplyDTO.getEmptyCar())
                .eq(StrUtil.isNotBlank(closedHazardCarApplyDTO.getHazardType()), ClosedHazardCarApplyEntity::getHazardType, closedHazardCarApplyDTO.getHazardType())
                .eq(ObjUtil.isNotNull(closedHazardCarApplyDTO.getAuditStatus()), ClosedHazardCarApplyEntity::getAuditStatus, closedHazardCarApplyDTO.getAuditStatus())
                .eq(StrUtil.isNotBlank(closedHazardCarApplyDTO.getStatus()), ClosedHazardCarApplyEntity::getStatus, closedHazardCarApplyDTO.getStatus())
                .ge(ObjUtil.isNotNull(closedHazardCarApplyDTO.getStartTime()), ClosedHazardCarApplyEntity::getPlanEnterTime, closedHazardCarApplyDTO.getStartTime())
                .le(ObjUtil.isNotNull(closedHazardCarApplyDTO.getEndTime()), ClosedHazardCarApplyEntity::getPlanLeaveTime, closedHazardCarApplyDTO.getEndTime())
                .like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getLicencePlateNum, closedHazardCarApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getBillNo, closedHazardCarApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getDriverName, closedHazardCarApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getAcceptName, closedHazardCarApplyDTO.getKeyword())
                .or().like(StrUtil.isNotBlank(closedHazardCarApplyDTO.getKeyword()), ClosedHazardCarApplyEntity::getSupercargoName, closedHazardCarApplyDTO.getKeyword());
        wrapper.orderByAsc(ClosedHazardCarApplyEntity::getAuditStatus);
        return closedHazardCarApplyService.exportExcel(closedHazardCarApplyService.list(wrapper));
    }

    /**
     * 导入excel 表格
     * @param closedHazardCarApplyExcelDtoList 查询条件
     * @param bindingResult 错误信息列表
     * @return ok fail
     */
    @PostMapping("/import")
    @PreAuthorize("@pms.hasPermission('visitor_hazardapply_export')")
    @CacheEvict(value = CacheConstants.CLOSE_HAZARD_APPLY, allEntries = true)
    public R importExcel(@RequestExcel List<ClosedHazardCarApplyExcelDTO> closedHazardCarApplyExcelDtoList, BindingResult bindingResult) {
        return closedHazardCarApplyService.importExcel(closedHazardCarApplyExcelDtoList, bindingResult);
    }
}
